/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package coalescent.cef.pui.pob;

import cef.pui.pob.Builder;
import cef.pui.pob.BuilderException;

import coalescent.br.BRWComp;
import coalescent.br.comps.BRWComps;

import commons.util.ValidationUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.xml.bind.PropertyException;

/**
 * Builds a list of computations to be performed by {@code BRWalker}.
 *
 * @author Susanta Tewari
 * @version 2.0.0
 * @history Created on 12/8/2010
 * @since 2.0.0
 */
final class BRComputationsBuilder extends Builder<List<BRWComp<?, ?>>> {

    /** Field description */
    private static final String PROP_EXACT_PROB = "exactProb";

    /** Field description */
    private static final String PROP_CONFIG_COUNTER = "configCounter";

    /** Field description */
    private static final String PROP_GENEALOGY_COUNTER = "genealogyCounter";

    /** Field description */
    private static final String PROP_CONFIG_BUILDER = "configBuilder";

    /** Field description */
    private static final String PROP_GENEALOGY_BUILDER = "genealogyBuilder";

    BRComputationsBuilder(String propertyKeyPrefix, Properties props) throws BuilderException {

        super(propertyKeyPrefix, props);

        addPropertyKey(PROP_EXACT_PROB);
        addPropertyKey(PROP_CONFIG_COUNTER);
        addPropertyKey(PROP_GENEALOGY_COUNTER);
        addPropertyKey(PROP_CONFIG_BUILDER);
        addPropertyKey(PROP_GENEALOGY_BUILDER);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    @Override
    protected List<BRWComp<?, ?>> buildFromProps() {

        List<BRWComp<?, ?>> computations = new ArrayList<>(10);
        String exactProbKey              = getFullPropertyKey(PROP_EXACT_PROB);
        String configCounterKey          = getFullPropertyKey(PROP_CONFIG_COUNTER);
        String genealogyCounterKey       = getFullPropertyKey(PROP_GENEALOGY_COUNTER);
        String configBuilderKey          = getFullPropertyKey(PROP_CONFIG_BUILDER);
        String genealogyBuilderKey       = getFullPropertyKey(PROP_GENEALOGY_BUILDER);


        // check property exists and is not empty
        try {

            ValidationUtil.validateProperty(configCounterKey, getProperty(configCounterKey));
            ValidationUtil.validateProperty(configCounterKey, getProperty(configCounterKey));
            ValidationUtil.validateProperty(genealogyCounterKey, getProperty(genealogyCounterKey));
            ValidationUtil.validateProperty(configBuilderKey, getProperty(configBuilderKey));
            ValidationUtil.validateProperty(genealogyBuilderKey, getProperty(genealogyBuilderKey));

        } catch (PropertyException ex) {
            throw new BuilderException("Invalid property for RecursionComputationsBuilder", ex);
        }


        // parse the booleans
        boolean exactProb, configCounter, genealogyCounter, configBuilder, genealogyBuilder;

        try {

            exactProb        = Boolean.parseBoolean(getProperty(exactProbKey));
            configCounter    = Boolean.parseBoolean(getProperty(configCounterKey));
            genealogyCounter = Boolean.parseBoolean(getProperty(genealogyCounterKey));
            configBuilder    = Boolean.parseBoolean(getProperty(configBuilderKey));
            genealogyBuilder = Boolean.parseBoolean(getProperty(genealogyBuilderKey));

        } catch (NumberFormatException ex) {
            throw new BuilderException("", ex);
        }


        // load the computations
        if (exactProb) {
            computations.add(BRWComps.getExactProbComputer());
        }

        if (configCounter) {
            computations.add(BRWComps.getConfigCounter());
        }

        if (genealogyCounter) {
            computations.add(BRWComps.getGenealogyCounter());
        }

        if (configBuilder) {
            computations.add(BRWComps.getConfigBuilder());
        }

        if (genealogyBuilder) {
            computations.add(BRWComps.getGenealogyBuilder());
        }

        return computations;
    }
}
